package com.xiaoxin.experience.system.properties;

import com.xiaoxin.experience.system.config.DataConfig;
import com.xiaoxin.experience.util.FileUtil;
import com.xiaoxin.experience.util.SystemUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertiesPropertySource;

import java.util.Properties;

/**
 * @author xiaoxin
 * 加载外部配置文件
 */
public class LoadEnvironmentPropertiesProcessor implements EnvironmentPostProcessor, Ordered
{
    private static final Logger LOG = LoggerFactory.getLogger(LoadEnvironmentPropertiesProcessor.class);

    @Override
    public int getOrder()
    {
        return Ordered.HIGHEST_PRECEDENCE;
    }

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application)
    {
        //此时日志组件还没有初始化，暂时同时使用标准输出打印
        LOG.debug("postProcessEnvironment Begin.");

        PropertiesHelper.createCacheFile();

        Properties cacheProperties = PropertiesHelper.loadPropertiesFromDisk();
        if (null == cacheProperties)
        {
            LOG.error("load cache properties fail.");
            return;
        }
        cacheProperties.setProperty("spring.datasource.driver-class-name","org.h2.Driver");
        cacheProperties.setProperty("spring.datasource.url", DataConfig.CONNECTION_URL);
        cacheProperties.setProperty("spring.datasource.username",DataConfig.CONNECTION_USERNAME);
        cacheProperties.setProperty("spring.datasource.password",DataConfig.CONNECTION_PASSWORD);
        portChoose(environment,cacheProperties);

        LOG.debug("postProcessEnvironment cache properties is: {}", cacheProperties);

        MutablePropertySources propertySources = environment.getPropertySources();
        //addLast 结合下面的 getOrder() 保证顺序
        propertySources.addLast(new PropertiesPropertySource("applicationConfig", cacheProperties));

        LOG.debug("postProcessEnvironment Finish.");
    }

    private void portChoose(ConfigurableEnvironment environment,Properties cacheProperties)
    {
        Integer httpPort = environment.getProperty("http.server.port",Integer.class,80);
        Integer httpsPort = environment.getProperty("server.port",Integer.class,443);
        int availablePort = SystemUtil.getAvailablePort(httpPort);
        saveHttpPort(availablePort);
        cacheProperties.setProperty("http.server.port", String.valueOf(availablePort));
        if (SystemUtil.isAvailablePort(httpsPort))
        {
            return;
        }
        cacheProperties.setProperty("server.port",String.valueOf(SystemUtil.getAvailablePortSpecFrom(availablePort + 1)));
    }

    private static void saveHttpPort(int httpPort)
    {
        FileUtil.writeToFile(String.valueOf(httpPort),"listenPort",false);
    }

}

